home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d2
/
sysid47.arc
/
SYSID.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-12-17
|
8KB
|
517 lines
page 75, 110
;--------------------------------------------------------------------
;
; SYSID.ASM
;
; Version 4.7
;
; Two subprograms used by SYSID.PAS:
;
; CPUID - identifies host CPU and NDP (if
; any)
; DISKREAD - reads absolute sectors from disk
;
; Steve Grant
; Long Beach, CA
; July 31, 1989
;
;--------------------------------------------------------------------
.8086
.8087
public CPUID, DISKREAD
CODE segment byte
;--------------------------------------------------------------------
CPUID proc near
assume cs:CODE, ds:DATA, es:nothing, ss:nothing
; On entry:
;
; BP
; SP => near return address
; offset of a cpu_info_t record
; segment " " " "
;
; On exit, the cpu_info_t record has been filled in as follows:
;
; byte = CPU type
; word = Machine Status Word
; 6 bytes = Global Descriptor Table
; 6 bytes = Interrupt Descriptor Table
; boolean = segment register change/interrupt flag
; boolean = 80386 multiplication bug flag
; byte = NDP type
; word = NDP control word
mCPU equ byte ptr [bx]
mMSW equ [bx + 1]
mGDT equ [bx + 3]
mIDT equ [bx + 9]
mopsize equ byte ptr [bx + 15]
mchkint equ byte ptr [bx + 16]
mmult equ byte ptr [bx + 17]
mNDP equ byte ptr [bx + 18]
mNDPCW equ [bx + 19]
f8088 equ 0
f8086 equ 1
fV20 equ 2
fV30 equ 3
f80188 equ 4
f80186 equ 5
f80286 equ 6
f80386 equ 7
funk = 0FFH
false equ 0
true equ 1
push bp
mov bp, sp
push ds
lds bx, [bp + 4]
call cpu
call chkint
call ndp
pop ds
pop bp
ret 4
;--------------------------------------------------------------------
cpu proc near
; interrupt of multi-prefix string instruction
sti
mov cx, 0FFFFH
rep lods byte ptr es : [si]
jcxz cpu_03
call piq
cmp dx, 4
jne cpu_01
mov mCPU, f8088
ret
cpu_01:
cmp dx, 6
je cpu_02
jmp cpu_12
cpu_02:
mov mCPU, f8086
ret
cpu_03:
; number of bits in displacement register used by shift
mov al, 0FFH
mov cl, 20H
shl al, cl
or al, al
jnz cpu_05
call piq
cmp dx, 4
jne cpu_04
mov mCPU, fV20
ret
cpu_04:
cmp dx, 6
jne cpu_12
mov mCPU, fV30
ret
cpu_05:
; order of write/decrement by PUSH SP
push sp
pop ax
cmp ax, sp
je cpu_07
call piq
cmp dx, 4
jne cpu_06
mov mCPU, f80188
ret
cpu_06:
cmp dx, 6
jne cpu_12
mov mCPU, f80186
ret
cpu_07:
.286P
smsw mMSW
sgdt mGDT
sidt mIDT
.8086
; try to alter flag register bits 15-12
pushf
pop ax
mov cx, ax
xor cx, 0F000H
push cx
popf
pushf
pop cx
cmp ax, cx
jne cpu_08
mov mCPU, f80286
ret
cpu_08:
mov mCPU, f80386
pushf
mov ax, sp
popf
inc ax
inc ax
cmp ax, sp
jnz cpu_09
mov mopsize, false
jmp short cpu_10
cpu_09:
mov mopsize, true
cpu_10:
.386P
mov eax, 0417A000H
mov ecx, 81H
mul ecx
cmp edx, 2
jne short cpu_11
cmp eax, 0FE7A000H
jne short cpu_11
mov mmult, true
ret
cpu_11:
mov mmult, false
ret
; BIX ibm.at/hardware #4663
.8086
cpu_12:
mov mCPU, funk
ret
cpu endp
;--------------------------------------------------------------------
piq proc near
; On exit:
;
; DX = length of prefetch instruction queue
;
; This subroutine uses self-modifying code but can nevertheless
; be run repeatedly in the course of the calling program.
count = 7
opincdx equ 42H ; inc dx opcode
opnop equ 90H ; nop opcode
mov al, opincdx
mov cx, count
push cx
push cs
pop es
mov di, offset piq_01 - 1
push di
std
rep stosb
mov al, opnop
pop di
pop cx
xor dx, dx
cli
rep stosb
rept count
inc dx
endm
piq_01:
sti
ret
piq endp
;--------------------------------------------------------------------
chkint proc near
; save old INT 01H vector
push bx
mov ax, 3501H
int 21H
mov old_int01_ofs, bx
mov old_int01_seg, es
pop bx
; redirect INT 01H vector
push ds
mov ax, 2501H
mov dx, seg new_int01
mov ds, dx
mov dx, offset new_int01
int 21H
pop ds
; set TF and change SS -- did we trap on following instruction?
pushf
pop ax
or ah, 01H ; set TF
push ax
popf
push ss ; CPU may wait one
; instruction before
; recognizing single step
; interrupt
pop ss
chkint_01: ; shouldn't ever trap here
; restore old INT 01H vector
push ds
mov ax, 2501H
lds dx, old_int01
int 21H
pop ds
ret
;--------------------------------------------------------------------
new_int01:
; INT 01H handler (single step)
;
; On entry:
;
; SP => IP
; CS
; flags
sti
pop ax ; IP
cmp ax, offset chkint_01
jb new_int01_03
je new_int01_01
mov mchkint, true
jmp short new_int01_02
new_int01_01:
mov mchkint, false
new_int01_02:
pop cx ; CS
pop dx ; flags
and dh, 0FEH ; turn off TF
push dx ; flags
push cx ; CS
new_int01_03:
push ax ; IP
iret
chkint endp
;--------------------------------------------------------------------
ndp proc near
fnone equ 0
f8087 equ 1
f80287 equ 2
f80387 equ 3
funk = 0FFH
mov ndp_cw, 0000H
cli
; The next three 80x87 instructions cannot carry the WAIT prefix,
; because there may not be an 80x87 for which to wait. The WAIT is
; therefore emulated with a MOV CX,<value>! LOOP $ combination.
; CPU NDP
fnsave ndp_save ; 14 221
mov cx, (221 - 23 + 16) / 17 + 1 ; 4
loop $ ; 17*CX+5
; 17*CX+23
fninit ; 8 8
mov cx, (8 - 17 + 16) / 17 + 1 ; 4
loop $ ; 17*CX+5
; 17*CX+17
fnstcw ndp_cw ; 14 24
mov cx, (24 - 23 + 16) / 17 + 1 ; 4
loop $ ; 17*CX+5
; 17*CX+23
sti
mov ax, ndp_cw
cmp ax, 0000H
jne ndp_01
mov mNDP, fnone
ret
ndp_01:
cmp ax, 03FFH
jne ndp_02
mov mNDP, f8087
jmp short ndp_04
ndp_02:
cmp ax, 037FH
jne ndp_05
fld1
fldz
fdiv
fld1
fchs
fldz
fdiv
fcom
fstsw ndp_sw
mov ax, ndp_sw
and ah, 41H ; C3, C0
cmp ah, 40H ; ST(0) = ST(1)
jne ndp_03
mov mNDP, f80287
jmp short ndp_04
ndp_03:
cmp ah, 01H ; ST(0) < ST(1)
jne ndp_05
mov mNDP, f80387
ndp_04:
frstor ndp_save
fstcw mNDPCW
ret
ndp_05:
mov mNDP, funk
ret
ndp endp
CPUID endp
;--------------------------------------------------------------------
DISKREAD proc near
assume cs : CODE, ds : nothing, es : nothing
; On entry:
;
; BP
; SP => near return address
; offset of disk buffer
; segment " " "
; number of sectors to read
; starting logical sector number
; drive number (0=A, 1=B, etc.)
;
; On exit:
;
; AX = function result
; 00 - function successful
; 01..FF - DOS INT 25H error result
drive equ [bp + 12]
starting_sector equ [bp + 10]
number_of_sectors equ [bp + 8]
buffer equ [bp + 4]
push bp
mov bp, sp
mov al, drive
mov dx, starting_sector
mov cx, number_of_sectors
push ds
lds bx, buffer
int 25H
inc sp ; fix broken stack
inc sp
pop ds
jc diskread_01
xor ax, ax
diskread_01:
pop bp
ret 10
DISKREAD endp
CODE ends
;--------------------------------------------------------------------
DATA segment byte
; storage for CPUID
; redirected INT 01H vector
old_int01 label dword
old_int01_ofs dw ?
old_int01_seg dw ?
; storage for NDPID
; 80x87 control word after initialization, status word after divide by zero
ndp_cw dw ?
ndp_save db 94 dup (?)
ndp_sw dw ?
DATA ends
end